package com.liangzong.betspider.task;


import com.google.common.collect.Lists;
import com.liangzong.betspider.Exceptions.NoOtherMatchException;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.LocalDateTime;
import java.util.List;

import static com.liangzong.betspider.utils.DriverUtil.gotoMatchListPage;
import static com.liangzong.betspider.utils.ProcessDataUtil.getStrByReg;
import static com.liangzong.betspider.utils.SpiderInfoUtil.*;

@Slf4j
public class CycleTask extends Thread {
    WebDriver driver;
    private final static String emptyPage = "data:,";
    private final static String listPage = "IP/B1";
    private final static String matchListPage = "IP/EV";
    private final static String HOME = "https://www.365365304.com/#/IP/B1";
    private long pauseTime;
    private int overTime;
    private boolean reverse;
    private volatile boolean stop;
    private boolean stoped;
    String sessionId;

    CycleTask(String sessionId, WebDriver driver, long pauseTime, boolean reverse) {
        this.driver = driver;
        this.pauseTime = pauseTime;
        this.reverse = reverse;
        this.sessionId = sessionId;
    }

    public void stopCycleTask() {
        log.info("设置CycleTask 停止工作");
        this.stop = true;
    }

    @Override
    public void run() {
        //已执行轮数数 间隔多少轮后刷新
        int cycleTimes = 0;
        int druingTimes = 10;
        boolean isFirstTime = true;
        WebElement footballMenu = null;
        do {
            try {

                if (cycleTimes != 0 && cycleTimes % druingTimes == 0) {
                    log.info("第{} 开始刷新", cycleTimes / druingTimes);
                    driver.navigate().refresh();
                }
                log.info("开始下一轮-------driver.getCurrentUrl()=" + driver.getCurrentUrl() + "-------------------------------------------------------------------------------------------------------");
                if (driver.getCurrentUrl().indexOf(matchListPage) == -1) {

                    if (driver.getCurrentUrl().indexOf(listPage) != -1) {
                        gotoMatchListPage(driver, isFirstTime);
                    } else if (driver.getCurrentUrl().equals(emptyPage)) {
                        driver.get(HOME);
                        pause(10 * 1000L);
                        continue;
                    }
                } else {
                    //如果需要刷新
                    if (getRefreshState(sessionId)) {
                        driver.navigate().refresh();
                        updateRefreshStateSuccess(sessionId);
                        pause(10 * 1000l);
                    } else if (needToRefresh(sessionId)) {
                        driver.navigate().refresh();
                        pause(10 * 1000l);
                    }
                }
                isFirstTime = false;
                clearTimeInfo();

                if (footballMenu == null) {
                    footballMenu = findMenu();
                }
                openMatch(footballMenu);

            } catch (NoOtherMatchException e) {
                //设置菜单为空 重新获取
                footballMenu = null;
                driver.get(HOME);
                pause(20 * 1000L);
                log.error(e.getMessage(), e);
                continue;
            } catch (Exception e) {
                //设置菜单为空 重新获取
                footballMenu = null;
                log.error(e.getMessage(), e);
            }
            cycleTimes++;
            pause(2 * 1000L);
        } while (!stop);
        log.info("CycleTask 已结束工作");
        stoped = true;
    }

    public boolean isStoped(){
        return stoped;
    }
    public WebElement findMenu() {
        WebElement openedClz = driver.findElement(By.cssSelector("div[class='ipn-Classification ipn-Classification-open '"));
        WebElement label = openedClz.findElement(By.cssSelector("span[class='ipn-ClassificationButton_Label ']"));
        if (label.getText().indexOf("足球") != -1) {
            return openedClz;
        }
        return null;
    }


    private void openMatch(WebElement footballMenu) {
        if (footballMenu == null) {
            return;
        }
        List<WebElement> closedClassifications = footballMenu.findElements(By.cssSelector("div[class^='ipn-Competition ipn-Competition-closed ']"));
        List<WebElement> openedClassifications = footballMenu.findElements(By.cssSelector("div[class^='ipn-Competition ']"));

        //点开所有地区联赛
        for (WebElement element1 : closedClassifications) {
            if (element1.getText().indexOf("足球电竞") != -1) {
                if (!openedClassifications.isEmpty()) {
                    log.info("已经打开联赛菜单，不再打开电竞菜单");
                    continue;
                }
            }
            element1.click();
        }
        List<WebElement> fixture_Wrapper = footballMenu.findElements(By.cssSelector("div[class='ipn-Fixture_Wrapper']"));
        putNumOfElement(fixture_Wrapper.size());
        //轮流点击所有比赛
        int i = 0;
        //如果从后往前遍历
        if (reverse) {
            fixture_Wrapper = Lists.reverse(fixture_Wrapper);
        }
        for (WebElement element1 : fixture_Wrapper) {

            try {
                if(stop){
                    return;
                }
                if (element1.isEnabled()) {
                    if (i != 0 && i % 10 == 0) {
                        ((RemoteWebDriver)driver).executeScript("arguments[0].scrollIntoView();", element1);
                    }
                    WebElement timeElement = element1.findElement(By.className("ipn-Fixture_TimerContainer"));
                    String time = timeElement.getText();
                    element1.click();
                    String currentUrl = driver.getCurrentUrl();
                    String url = getStrByReg(currentUrl, "EV(\\d.*?)C1");
                    putTimeInfo(url, time);
                }
            } catch (ElementClickInterceptedException e) {
                log.error(e.getMessage());
            } catch (StaleElementReferenceException e) {
                log.error(e.getMessage());
            } catch (Exception e) {
                throw e;
            }

            i++;
            pause(pauseTime);
        }
        clearTimeInfo();

    }

    private static void pause() {
        pause(500L);
    }

    private static void pause(Long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

